#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/fb.h>

int main(int argc, char const *argv[])
{
    int lcd = open("/dev/fb0",O_RDWR);
    if(lcd == -1)
    {
        perror("打开缓冲失败！");
        exit(0);
    }

    // 自动获取硬件参数
    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;
    ioctl(lcd,FBIOGET_FSCREENINFO,&finfo);
    ioctl(lcd,FBIOGET_VSCREENINFO,&vinfo); //获取屏幕信息 
    
    int lcd_w = vinfo.xres;
    int lcd_h = vinfo.yres;
    int bpp = vinfo.bits_per_pixel;
    int screen_size = lcd_w*lcd_h*bpp/8;

    char *p = mmap(NULL,screen_size*2,PROT_READ|PROT_WRITE,MAP_SHARED,lcd,0);
    if(p == MAP_FAILED)
    {
        perror("内容映射失败！");
        exit(0);
    }

    // int red = 0x00FF0000;
    // int green = 0x0000FF00;
    // int blue = 0x000000FF;
    int corol[3] = {0x00FFFFFF,0x00FFFF00,0x0000FFFF};

    // 开始lcd屏位置
    vinfo.xoffset = 0;
    vinfo.yoffset = 0;
    ioctl(lcd,FBIOGET_DISPINFO,&vinfo);

    for(int k = 0;;k++)
    {
        int offset = screen_size*((k+1)%2);
        for(int i=0;i<lcd_w*lcd_h;i++)
        {
            memcpy(p+4*i+offset,&corol[k%3],4);
        }
        // 改变LCD屏显示区域
        vinfo.xoffset = 0;
        vinfo.yoffset = 480*((k+1)%2);
        ioctl(lcd,FBIOPAN_DISPLAY,&vinfo);

        usleep(100000);
    }

    // for(int i = 0;i<800*160;i++)
    // {
    //     memcpy(p+4*i,&red,4);
    // }

    //  for(int i = 0;i < 800*160;i++)
    // {
    //     memcpy(p+4*i+800*160*4,&green,4);
    // }

    // for(int i=0;i < 800*160;i++)
    // {
    //     memcpy(p+4*i+800*320*4,&blue,4);
    // }


    munmap(p,800*400*4);
    close(lcd);

    return 0;
}
